// utils/token-extractor.js
// Token提取工具 - 尝试多种方法从响应头中提取Token

class TokenExtractor {
  constructor() {
    this.tokenKeys = [
      'X-Subject-Token',
      'x-subject-token',
      'X-SUBJECT-TOKEN',
      'x_subject_token',
      'subject-token',
      'Subject-Token',
      'token',
      'Token',
      'TOKEN'
    ]
  }

  // 方法1: 直接访问
  extractTokenMethod1(response) {
    console.log('=== 方法1: 直接访问 ===')
    
    for (const key of this.tokenKeys) {
      try {
        if (response.header && response.header[key]) {
          const token = response.header[key]
          console.log(`✅ 方法1成功 - 键名: ${key}`)
          return { success: true, token, method: 'direct', key }
        }
      } catch (error) {
        console.log(`❌ 方法1失败 - 键名: ${key}, 错误: ${error.message}`)
      }
    }
    
    return { success: false, method: 'direct' }
  }

  // 方法2: 使用Object.getOwnPropertyDescriptor
  extractTokenMethod2(response) {
    console.log('=== 方法2: Object.getOwnPropertyDescriptor ===')
    
    if (!response.header) {
      return { success: false, method: 'getOwnPropertyDescriptor' }
    }
    
    for (const key of this.tokenKeys) {
      try {
        const descriptor = Object.getOwnPropertyDescriptor(response.header, key)
        if (descriptor && descriptor.value) {
          const token = descriptor.value
          console.log(`✅ 方法2成功 - 键名: ${key}`)
          return { success: true, token, method: 'getOwnPropertyDescriptor', key }
        }
      } catch (error) {
        console.log(`❌ 方法2失败 - 键名: ${key}, 错误: ${error.message}`)
      }
    }
    
    return { success: false, method: 'getOwnPropertyDescriptor' }
  }

  // 方法3: 使用Reflect.get
  extractTokenMethod3(response) {
    console.log('=== 方法3: Reflect.get ===')
    
    if (!response.header) {
      return { success: false, method: 'Reflect.get' }
    }
    
    for (const key of this.tokenKeys) {
      try {
        const token = Reflect.get(response.header, key)
        if (token) {
          console.log(`✅ 方法3成功 - 键名: ${key}`)
          return { success: true, token, method: 'Reflect.get', key }
        }
      } catch (error) {
        console.log(`❌ 方法3失败 - 键名: ${key}, 错误: ${error.message}`)
      }
    }
    
    return { success: false, method: 'Reflect.get' }
  }

  // 方法4: 遍历所有属性
  extractTokenMethod4(response) {
    console.log('=== 方法4: 遍历所有属性 ===')
    
    if (!response.header) {
      return { success: false, method: 'iterate' }
    }
    
    try {
      const headerKeys = Object.keys(response.header)
      console.log('所有响应头键名:', headerKeys)
      
      // 查找包含token的键名
      const tokenRelatedKeys = headerKeys.filter(key => 
        key.toLowerCase().includes('token') || 
        key.toLowerCase().includes('subject')
      )
      
      console.log('包含token或subject的键名:', tokenRelatedKeys)
      
      for (const key of tokenRelatedKeys) {
        try {
          const token = response.header[key]
          if (token && typeof token === 'string' && token.length > 10) {
            console.log(`✅ 方法4成功 - 键名: ${key}`)
            return { success: true, token, method: 'iterate', key }
          }
        } catch (error) {
          console.log(`❌ 方法4失败 - 键名: ${key}, 错误: ${error.message}`)
        }
      }
    } catch (error) {
      console.log(`❌ 方法4遍历失败: ${error.message}`)
    }
    
    return { success: false, method: 'iterate' }
  }

  // 方法5: 检查响应数据
  extractTokenMethod5(response) {
    console.log('=== 方法5: 检查响应数据 ===')
    
    if (response.data) {
      console.log('响应数据类型:', typeof response.data)
      console.log('响应数据键名:', Object.keys(response.data))
      
      // 检查响应数据中是否包含token
      const dataKeys = Object.keys(response.data)
      const tokenRelatedKeys = dataKeys.filter(key => 
        key.toLowerCase().includes('token') || 
        key.toLowerCase().includes('subject')
      )
      
      if (tokenRelatedKeys.length > 0) {
        console.log('响应数据中包含token的键名:', tokenRelatedKeys)
        for (const key of tokenRelatedKeys) {
          const value = response.data[key]
          console.log(`  ${key}: ${value}`)
        }
      }
    }
    
    return { success: false, method: 'response_data' }
  }

  // 方法6: 使用JSON.stringify和JSON.parse
  extractTokenMethod6(response) {
    console.log('=== 方法6: JSON序列化 ===')
    
    try {
      const headerStr = JSON.stringify(response.header)
      console.log('响应头JSON字符串:', headerStr)
      
      // 查找X-Subject-Token
      const tokenMatch = headerStr.match(/"X-Subject-Token"\s*:\s*"([^"]+)"/)
      if (tokenMatch) {
        const token = tokenMatch[1]
        console.log(`✅ 方法6成功 - 从JSON字符串中提取`)
        return { success: true, token, method: 'json_stringify', key: 'X-Subject-Token' }
      }
      
      // 查找其他可能的token键名
      for (const key of this.tokenKeys) {
        const pattern = new RegExp(`"${key}"\\s*:\\s*"([^"]+)"`)
        const match = headerStr.match(pattern)
        if (match) {
          const token = match[1]
          console.log(`✅ 方法6成功 - 键名: ${key}`)
          return { success: true, token, method: 'json_stringify', key }
        }
      }
    } catch (error) {
      console.log(`❌ 方法6失败: ${error.message}`)
    }
    
    return { success: false, method: 'json_stringify' }
  }

  // 运行所有提取方法
  extractToken(response) {
    console.log('=== 开始Token提取 ===')
    console.log('完整响应对象:', response)
    console.log('响应对象类型:', typeof response)
    console.log('响应对象键名:', Object.keys(response))
    console.log('响应状态码:', response.statusCode)
    console.log('响应状态:', response.status)
    console.log('响应数据:', response.data)
    console.log('响应头:', response.header)
    console.log('响应头类型:', typeof response.header)
    console.log('响应头是否为null:', response.header === null)
    console.log('响应头是否为undefined:', response.header === undefined)
    
    // 检查response是否为空或无效
    if (!response) {
      console.log('❌ 响应对象为空或未定义')
      return { success: false, method: 'response_empty', error: '响应对象为空或未定义' }
    }
    
    if (response.statusCode !== 201 && response.statusCode !== 200) {
      console.log(`❌ 响应状态码不正确: ${response.statusCode}`)
      return { success: false, method: 'status_code_error', error: `状态码: ${response.statusCode}` }
    }
    
    if (!response.header) {
      console.log('❌ 响应头为空或未定义')
      return { success: false, method: 'header_empty', error: '响应头为空或未定义' }
    }
    
    const methods = [
      this.extractTokenMethod1.bind(this),
      this.extractTokenMethod2.bind(this),
      this.extractTokenMethod3.bind(this),
      this.extractTokenMethod4.bind(this),
      this.extractTokenMethod5.bind(this),
      this.extractTokenMethod6.bind(this)
    ]
    
    for (let i = 0; i < methods.length; i++) {
      const method = methods[i]
      const result = method(response)
      
      if (result.success) {
        console.log(`🎉 Token提取成功! 方法: ${result.method}, 键名: ${result.key}`)
        console.log(`Token值: ${result.token.substring(0, 20)}...`)
        return result
      }
    }
    
    console.log('❌ 所有Token提取方法都失败了')
    return { success: false, method: 'all_failed' }
  }
}

module.exports = new TokenExtractor()
